
Object.defineProperty(exports, "__esModule", { value: true });
/**
* @module call
* @author: Hjava
* @description: VOIP语音通话模块，设计见：https://wiki.sankuai.com/pages/viewpage.action?pageId=1134326409
* @since: 2018-07-21 15:49:07
*/
var call_constant_1 = __webpack_require__(/*! _call/call.constant */ "./src/core/call/call.constant.ts");
var call_session_1 = __webpack_require__(/*! _call/call.session */ "./src/core/call/call.session.ts");
var constant_1 = __webpack_require__(/*! _util/constant */ "./src/core/utils/constant.ts");
var deviceInfo_1 = __webpack_require__(/*! _util/deviceInfo */ "./src/core/utils/deviceInfo.ts");
var eventEmitter_1 = __webpack_require__(/*! _util/eventEmitter */ "./src/core/utils/eventEmitter.ts");
var log_1 = __webpack_require__(/*! ./../utils/log */ "./src/core/utils/log.ts");
var CallSDK = /** @class */ (function () {
    function CallSDK(loginSDK) {
        var _this = this;
        this._loginSDK = null;
        this._sendPingHandle = null;
        this._currentSid = null;
        this._createCbObject = {};
        this._inviteMap = {};
        this._pingTimeoutCount = 0;
        this._networkChangeFlag = false;
        this._PING_TIME = 5 * 1000;
        this.constant = call_constant_1.default;
        this._loginSDK = loginSDK;
        this._sendPingHandle = null;
        this._currentSid = null;
        this._createCbObject = {};
        this._inviteMap = {};
        this._pingTimeoutCount = 0;
        this._networkChangeFlag = false;
        // 收到电话邀请
        eventEmitter_1.default.on(call_constant_1.default.Call.URI_CALL_CREATE_ACK, this._onCreateAck.bind(this));
        eventEmitter_1.default.on(call_constant_1.default.Call.URI_CALL_INVITE, this._onInvite.bind(this));
        eventEmitter_1.default.on(call_constant_1.default.Call.URI_CALL_INVITE2, this._onInvite.bind(this));
        eventEmitter_1.default.on(call_constant_1.default.Call.URI_CALL_HALFWAY_INVITE, this._onInvite.bind(this));
        eventEmitter_1.default.on(call_constant_1.default.Call.URI_CALL_INVITE_ACK, this._onInviteAck.bind(this));
        eventEmitter_1.default.on(call_constant_1.default.Call.URI_CALL_DETECT_ACK, this._onDetectAck.bind(this));
        eventEmitter_1.default.on(call_constant_1.default.Call.URI_CALL_INVITE_RESPONSE_ACK, this._onInviteResponseAck.bind(this));
        eventEmitter_1.default.on(call_constant_1.default.Call.URI_CALL_MEMBER_CHANGE, this._onMemberChange.bind(this));
        eventEmitter_1.default.on(call_constant_1.default.Call.URI_CALL_NOTIFY, this._onNotice.bind(this));
        eventEmitter_1.default.on(call_constant_1.default.Call.URI_CALL_PING_ACK, this._onPingAck.bind(this));
        eventEmitter_1.default.on(call_constant_1.default.Call.URI_CALL_MEMBER_JOIN_ACK, this._onJoinAck.bind(this));
        eventEmitter_1.default.on(call_constant_1.default.Call.URI_CALL_QUALITY_NOTIFY, this._qualityNotice.bind(this));
        eventEmitter_1.default.on(constant_1.LOGIN_STATUS_CHANGE_EVENT, (function (status) {
            switch (status) {
                case constant_1.LOGIN_STATUS.DISCONNECTED: {
                    _this._networkChangeFlag = true;
                    break;
                }
                case constant_1.LOGIN_STATUS.AUTHENTICATED: {
                    if (_this._currentSid) {
                        _this._sendDetect({
                            sid: _this._currentSid
                        });
                    }
                    break;
                }
            }
        }).bind(this));
    }
    CallSDK.prototype.send = function (message) {
        try {
            this._loginSDK._sendTransUp(call_constant_1.default.SVID_CALL_SIGNAL, message);
        }
        catch (e) {
            log_1.default.error(e);
        }
    };
    /**
     * 主动发起调用
     * message: {callType: 视频/音频, peerUid: 被邀请方（即对方）uid}
     */
    CallSDK.prototype.sendCall = function (message, cb) {
        this._sendCreate();
        this._createCbObject = {
            message: message,
            cb: cb
        };
    };
    /**
     * 主动拨号，发送方create->ack->invite->ack->[ping]
     * 必须包含下面几个信息
     * uid, name, peerUid, callType
     */
    CallSDK.prototype._sendCreate = function () {
        this.send(new call_session_1.default.PCallCreate({
            uid: this._loginSDK.getUID()
        }));
    };
    CallSDK.prototype._onCreateAck = function (ack) {
        var _this = this;
        eventEmitter_1.default.emit(constant_1.CALL_EVENT.CREATE_ACK, ack);
        this._currentSid = ack.sid;
        // 这里做一个缓存队列，存储callback
        // var self = this;
        var createCallback = this._createCbObject.cb;
        var message = this._createCbObject.message;
        this._createCbObject = {};
        if (createCallback) {
            createCallback({
                sid: ack.sid,
                callType: message.callType
            }).then(function () {
                _this._sendInvite({
                    uid: _this._loginSDK.getUID(),
                    sid: ack.sid,
                    peerAppid: 1,
                    name: message.name,
                    peerUid: message.peerUid,
                    callType: message.callType
                });
            });
        }
    };
    CallSDK.prototype._sendInvite = function (message) {
        this.send(new call_session_1.default.PCallInvite(message));
    };
    CallSDK.prototype._onInviteAck = function (ack) {
        eventEmitter_1.default.emit(constant_1.CALL_EVENT.INVITE_ACK, ack);
        if (ack.rescode === 0) {
            this.startSendPing();
        }
    };
    /**
     * 接收方收到邀请：接收方：onInvite->detect->ack->inviteResponse->ack->[ping]
     * 可能同时收到多个相同的invite，只需要处理第一个，后面过滤即可
     */
    CallSDK.prototype._onInvite = function (message) {
        if (this._inviteMap[message.sid]) {
            return;
        }
        this._currentSid = message.sid;
        try {
            this._sendDetect({
                sid: message.sid
            });
        }
        catch (e) {
            log_1.default.error(e);
        }
        this._inviteMap[message.sid] = message;
        eventEmitter_1.default.emit(constant_1.CALL_EVENT.INVITE, message);
    };
    CallSDK.prototype._sendDetect = function (message) {
        message.uid = this._loginSDK.getUID();
        // 去掉PCallDetect干扰
        // this.send(new Session.PCallDetect(message));
    };
    CallSDK.prototype._onDetectAck = function (ack) {
        if (this._networkChangeFlag) {
            // 断线重连
            this._networkChangeFlag = false;
            if (ack.rescode === call_constant_1.default.RES_SUCCESS) {
                this.sendJoin({
                    sid: ack.sid
                });
            }
            else {
                this._currentSid = null;
            }
        }
        else {
            // 被叫方检测
            var inviteMessage = this._inviteMap[ack.sid];
            eventEmitter_1.default.emit(constant_1.CALL_EVENT.DETECT_ACK, ack, inviteMessage);
            delete this._inviteMap[ack.sid];
        }
    };
    /**
     * 收到invite后，发送response请求
     * ack->message.action=1->[ping]
     * {
     *  sid, 房间sid
     *  action 操作 accept: 1, busy: 2, reject: 3
     * }
     */
    CallSDK.prototype.sendInviteResponse = function (message) {
        message.uid = this._loginSDK.getUID();
        this.send(new call_session_1.default.PCallInivteResponse(message));
    };
    CallSDK.prototype._onInviteResponseAck = function (ack) {
        eventEmitter_1.default.emit(constant_1.CALL_EVENT.INVITE_RESPONSE_ACK, ack);
        if (ack.action === 1 && ack.rescode === 0) {
            this.startSendPing();
        }
    };
    /**
     * 发送
     * {sid: 房间sid}
     */
    CallSDK.prototype.sendJoin = function (message) {
        message.uid = this._loginSDK.getUID();
        this.send(new call_session_1.default.PCallJoin(message));
    };
    CallSDK.prototype._onJoinAck = function (ack) {
        eventEmitter_1.default.emit(constant_1.CALL_EVENT.JOIN, ack);
    };
    CallSDK.prototype.sendPing = function () {
        var uid = this._loginSDK.getUID();
        this.send(new call_session_1.default.PCallPing({
            uid: uid
        }));
        if (this._pingTimeoutCount > 5) {
            this.sendLeave({
                sid: this._currentSid
            });
            eventEmitter_1.default.emit(constant_1.CALL_EVENT.LEAVE);
        }
        this._pingTimeoutCount++;
    };
    CallSDK.prototype.startSendPing = function () {
        var _this = this;
        this.stopSendPing();
        this.sendPing();
        this._sendPingHandle = setInterval(function () {
            _this.sendPing();
        }, this._PING_TIME);
    };
    CallSDK.prototype.stopSendPing = function () {
        if (this._sendPingHandle !== null) {
            clearInterval(this._sendPingHandle);
            this._sendPingHandle = null;
        }
    };
    CallSDK.prototype._onPingAck = function (ack) {
        this._pingTimeoutCount = 0;
    };
    /**
     *
     */
    CallSDK.prototype._onMemberChange = function (message) {
        if (message.sid !== this._currentSid) {
            return;
        }
        eventEmitter_1.default.emit(constant_1.CALL_EVENT.MEMBER_CHANGE, message);
        //todo 如果房间只剩自己一个人时，是否需要挂断并离开
    };
    /**
     * 回的ACKMEMBER_CHANGE
     */
    CallSDK.prototype.sendLeave = function (message) {
        message.uid = this._loginSDK.getUID();
        this.send(new call_session_1.default.PCallLeave(message));
        this.clearCurrentData();
    };
    /**
     * 将接听和拒绝的状态同步给自己的其他设备和通话对方
     */
    CallSDK.prototype._onNotice = function (message) {
        eventEmitter_1.default.emit(constant_1.CALL_EVENT.NOTICE, message);
        if (message.uid === this._loginSDK.getUID() && message.deviceType !== deviceInfo_1.default.deviceType) {
            this.clearCurrentData();
        }
    };
    /**
     * 语音质量变化时推送
     */
    CallSDK.prototype._qualityNotice = function (message) {
        eventEmitter_1.default.emit(constant_1.CALL_EVENT.QUALITY_NOTICE, message);
    };
    CallSDK.prototype.clearCurrentData = function () {
        this.stopSendPing();
        this._currentSid = null;
    };
    CallSDK.constant = call_constant_1.default;
    CallSDK.Session = call_session_1.default;
    return CallSDK;
}());
exports.default = CallSDK;


//# sourceURL=webpack://MTDX/./src/core/call/index.ts?